#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Linux权限维持隐蔽性检测器
用于检测和评估已部署权限维持机制的隐蔽性
"""

import os
import sys
import json
import time
import subprocess
import hashlib
import re
from datetime import datetime
from pathlib import Path

class PersistenceStealthChecker:
    def __init__(self):
        self.session_id = datetime.now().strftime("%Y%m%d_%H%M%S")
        self.results = {
            'session_id': self.session_id,
            'timestamp': datetime.now().isoformat(),
            'stealth_score': 0,
            'detections': [],
            'recommendations': []
        }
        
        # 检测规则配置
        self.detection_rules = {
            'ssh_keys': {
                'paths': [
                    '~/.ssh/authorized_keys',
                    '/root/.ssh/authorized_keys',
                    '/home/*/.ssh/authorized_keys'
                ],
                'suspicious_patterns': [
                    r'system.*key',
                    r'backup.*key',
                    r'maintenance.*key',
                    r'\.hidden',
                    r'temp.*key'
                ]
            },
            'systemd_services': {
                'paths': [
                    '/etc/systemd/system/',
                    '/lib/systemd/system/',
                    '/usr/lib/systemd/system/'
                ],
                'suspicious_names': [
                    'log-cleaner',
                    'system-monitor',
                    'backup-service',
                    'maintenance-task',
                    'update-checker'
                ]
            },
            'cron_jobs': {
                'files': [
                    '/etc/crontab',
                    '/var/spool/cron/crontabs/root',
                    '/etc/cron.d/*'
                ],
                'suspicious_patterns': [
                    r'/tmp/\.',
                    r'system.*check',
                    r'maintenance',
                    r'backup.*script',
                    r'>/dev/null 2>&1'
                ]
            },
            'environment_vars': {
                'paths': [
                    '/etc/profile.d/',
                    '/etc/environment',
                    '/etc/bash.bashrc',
                    '~/.bashrc',
                    '~/.profile'
                ],
                'suspicious_patterns': [
                    r'SYSTEM.*CACHE',
                    r'maintenance.*mode',
                    r'if.*\[\[.*trigger',
                    r'export.*PATH.*cache'
                ]
            },
            'file_triggers': {
                'common_locations': [
                    '/tmp/',
                    '/var/tmp/',
                    '/var/log/',
                    '/dev/shm/'
                ],
                'trigger_patterns': [
                    r'\.sync',
                    r'\.trigger',
                    r'\.cmd',
                    r'\.cache'
                ]
            },
            'shell_aliases': {
                'files': [
                    '~/.bashrc',
                    '~/.zshrc',
                    '/etc/bash.bashrc'
                ],
                'suspicious_patterns': [
                    r'alias.*=.*if.*trigger',
                    r'alias.*ls.*=.*bash',
                    r'alias.*ps.*=.*bash'
                ]
            }
        }
    
    def log_info(self, message):
        """记录信息日志"""
        print(f"[INFO] {message}")
    
    def log_warning(self, message):
        """记录警告日志"""
        print(f"[WARNING] {message}")
    
    def log_error(self, message):
        """记录错误日志"""
        print(f"[ERROR] {message}")
    
    def log_detection(self, detection_type, details):
        """记录检测结果"""
        detection = {
            'type': detection_type,
            'timestamp': datetime.now().isoformat(),
            'details': details
        }
        self.results['detections'].append(detection)
        print(f"[DETECTION] {detection_type}: {details.get('description', 'Unknown')}")
    
    def run_command(self, command, shell=True):
        """执行系统命令"""
        try:
            result = subprocess.run(
                command,
                shell=shell,
                capture_output=True,
                text=True,
                timeout=30
            )
            return result.returncode == 0, result.stdout, result.stderr
        except subprocess.TimeoutExpired:
            return False, "", "Command timeout"
        except Exception as e:
            return False, "", str(e)
    
    def check_ssh_key_backdoors(self):
        """检测SSH密钥后门"""
        self.log_info("检测SSH密钥后门...")
        
        detections = []
        
        # 检查authorized_keys文件
        auth_key_files = [
            os.path.expanduser('~/.ssh/authorized_keys'),
            '/root/.ssh/authorized_keys'
        ]
        
        for auth_file in auth_key_files:
            if os.path.exists(auth_file):
                try:
                    with open(auth_file, 'r') as f:
                        content = f.read()
                    
                    # 检查可疑的密钥注释
                    for pattern in self.detection_rules['ssh_keys']['suspicious_patterns']:
                        if re.search(pattern, content, re.IGNORECASE):
                            detections.append({
                                'file': auth_file,
                                'pattern': pattern,
                                'description': f'在{auth_file}中发现可疑SSH密钥模式: {pattern}'
                            })
                    
                    # 检查密钥数量异常
                    key_count = len([line for line in content.split('\n') if line.strip() and not line.startswith('#')])
                    if key_count > 5:
                        detections.append({
                            'file': auth_file,
                            'key_count': key_count,
                            'description': f'{auth_file}中包含异常数量的SSH密钥: {key_count}个'
                        })
                
                except Exception as e:
                    self.log_error(f"读取{auth_file}失败: {e}")
        
        # 检查隐藏的SSH密钥文件
        ssh_dirs = [os.path.expanduser('~/.ssh'), '/root/.ssh']
        for ssh_dir in ssh_dirs:
            if os.path.exists(ssh_dir):
                for file in os.listdir(ssh_dir):
                    if file.startswith('.') and file not in ['.', '..']:
                        file_path = os.path.join(ssh_dir, file)
                        if os.path.isfile(file_path):
                            detections.append({
                                'file': file_path,
                                'description': f'发现隐藏的SSH密钥文件: {file_path}'
                            })
        
        for detection in detections:
            self.log_detection('SSH_KEY_BACKDOOR', detection)
        
        return len(detections) == 0
    
    def check_systemd_service_backdoors(self):
        """检测Systemd服务后门"""
        self.log_info("检测Systemd服务后门...")
        
        detections = []
        
        # 检查系统服务目录
        service_dirs = ['/etc/systemd/system/', '/lib/systemd/system/']
        
        for service_dir in service_dirs:
            if os.path.exists(service_dir):
                for service_file in os.listdir(service_dir):
                    if service_file.endswith('.service'):
                        service_path = os.path.join(service_dir, service_file)
                        
                        # 检查可疑的服务名称
                        service_name = service_file.replace('.service', '')
                        if service_name in self.detection_rules['systemd_services']['suspicious_names']:
                            detections.append({
                                'service': service_name,
                                'file': service_path,
                                'description': f'发现可疑的Systemd服务: {service_name}'
                            })
                        
                        # 检查服务文件内容
                        try:
                            with open(service_path, 'r') as f:
                                content = f.read()
                            
                            # 检查可疑的执行路径
                            if re.search(r'ExecStart=.*(/tmp/|/var/tmp/)', content):
                                detections.append({
                                    'service': service_name,
                                    'file': service_path,
                                    'description': f'服务{service_name}使用可疑的执行路径'
                                })
                            
                            # 检查自动重启配置
                            if 'Restart=always' in content:
                                detections.append({
                                    'service': service_name,
                                    'file': service_path,
                                    'description': f'服务{service_name}配置为自动重启'
                                })
                        
                        except Exception as e:
                            self.log_error(f"读取服务文件{service_path}失败: {e}")
        
        # 检查运行中的可疑服务
        success, output, _ = self.run_command("systemctl list-units --type=service --state=running")
        if success:
            for line in output.split('\n'):
                for suspicious_name in self.detection_rules['systemd_services']['suspicious_names']:
                    if suspicious_name in line:
                        detections.append({
                            'service': suspicious_name,
                            'status': 'running',
                            'description': f'发现运行中的可疑服务: {suspicious_name}'
                        })
        
        for detection in detections:
            self.log_detection('SYSTEMD_SERVICE_BACKDOOR', detection)
        
        return len(detections) == 0
    
    def check_cron_backdoors(self):
        """检测Cron定时任务后门"""
        self.log_info("检测Cron定时任务后门...")
        
        detections = []
        
        # 检查系统crontab文件
        cron_files = ['/etc/crontab']
        
        # 检查用户crontab
        success, output, _ = self.run_command("crontab -l")
        if success and output.strip():
            # 分析crontab内容
            for line in output.split('\n'):
                if line.strip() and not line.startswith('#'):
                    for pattern in self.detection_rules['cron_jobs']['suspicious_patterns']:
                        if re.search(pattern, line, re.IGNORECASE):
                            detections.append({
                                'cron_entry': line.strip(),
                                'pattern': pattern,
                                'description': f'发现可疑的Cron任务: {line.strip()}'
                            })
        
        # 检查cron.d目录
        cron_d_dir = '/etc/cron.d'
        if os.path.exists(cron_d_dir):
            for cron_file in os.listdir(cron_d_dir):
                cron_path = os.path.join(cron_d_dir, cron_file)
                if os.path.isfile(cron_path):
                    try:
                        with open(cron_path, 'r') as f:
                            content = f.read()
                        
                        for pattern in self.detection_rules['cron_jobs']['suspicious_patterns']:
                            if re.search(pattern, content, re.IGNORECASE):
                                detections.append({
                                    'file': cron_path,
                                    'pattern': pattern,
                                    'description': f'在{cron_path}中发现可疑模式: {pattern}'
                                })
                    
                    except Exception as e:
                        self.log_error(f"读取cron文件{cron_path}失败: {e}")
        
        for detection in detections:
            self.log_detection('CRON_BACKDOOR', detection)
        
        return len(detections) == 0
    
    def check_environment_variable_backdoors(self):
        """检测环境变量后门"""
        self.log_info("检测环境变量后门...")
        
        detections = []
        
        # 检查profile.d目录
        profile_d_dir = '/etc/profile.d'
        if os.path.exists(profile_d_dir):
            for script_file in os.listdir(profile_d_dir):
                if script_file.startswith('.'):  # 隐藏文件
                    script_path = os.path.join(profile_d_dir, script_file)
                    detections.append({
                        'file': script_path,
                        'description': f'发现隐藏的profile脚本: {script_path}'
                    })
                
                script_path = os.path.join(profile_d_dir, script_file)
                if os.path.isfile(script_path):
                    try:
                        with open(script_path, 'r') as f:
                            content = f.read()
                        
                        for pattern in self.detection_rules['environment_vars']['suspicious_patterns']:
                            if re.search(pattern, content, re.IGNORECASE):
                                detections.append({
                                    'file': script_path,
                                    'pattern': pattern,
                                    'description': f'在{script_path}中发现可疑环境变量模式: {pattern}'
                                })
                    
                    except Exception as e:
                        self.log_error(f"读取profile脚本{script_path}失败: {e}")
        
        # 检查shell配置文件
        shell_configs = [
            os.path.expanduser('~/.bashrc'),
            os.path.expanduser('~/.profile'),
            '/etc/bash.bashrc'
        ]
        
        for config_file in shell_configs:
            if os.path.exists(config_file):
                try:
                    with open(config_file, 'r') as f:
                        content = f.read()
                    
                    for pattern in self.detection_rules['environment_vars']['suspicious_patterns']:
                        if re.search(pattern, content, re.IGNORECASE):
                            detections.append({
                                'file': config_file,
                                'pattern': pattern,
                                'description': f'在{config_file}中发现可疑环境变量: {pattern}'
                            })
                
                except Exception as e:
                    self.log_error(f"读取配置文件{config_file}失败: {e}")
        
        for detection in detections:
            self.log_detection('ENVIRONMENT_VARIABLE_BACKDOOR', detection)
        
        return len(detections) == 0
    
    def check_file_trigger_backdoors(self):
        """检测文件触发后门"""
        self.log_info("检测文件触发后门...")
        
        detections = []
        
        # 检查常见的触发文件位置
        trigger_locations = ['/tmp', '/var/tmp', '/var/log', '/dev/shm']
        
        for location in trigger_locations:
            if os.path.exists(location):
                for item in os.listdir(location):
                    item_path = os.path.join(location, item)
                    
                    # 检查隐藏文件
                    if item.startswith('.'):
                        for pattern in self.detection_rules['file_triggers']['trigger_patterns']:
                            if re.search(pattern, item):
                                detections.append({
                                    'file': item_path,
                                    'pattern': pattern,
                                    'description': f'发现可疑的触发文件: {item_path}'
                                })
        
        # 检查文件监控进程
        success, output, _ = self.run_command("ps aux | grep -E '(file.*monitor|trigger.*watch)' | grep -v grep")
        if success and output.strip():
            for line in output.split('\n'):
                if line.strip():
                    detections.append({
                        'process': line.strip(),
                        'description': f'发现可疑的文件监控进程: {line.strip()}'
                    })
        
        for detection in detections:
            self.log_detection('FILE_TRIGGER_BACKDOOR', detection)
        
        return len(detections) == 0
    
    def check_shell_alias_backdoors(self):
        """检测Shell别名后门"""
        self.log_info("检测Shell别名后门...")
        
        detections = []
        
        # 检查shell配置文件中的别名
        shell_configs = [
            os.path.expanduser('~/.bashrc'),
            os.path.expanduser('~/.zshrc'),
            '/etc/bash.bashrc'
        ]
        
        for config_file in shell_configs:
            if os.path.exists(config_file):
                try:
                    with open(config_file, 'r') as f:
                        content = f.read()
                    
                    # 检查可疑的别名定义
                    for pattern in self.detection_rules['shell_aliases']['suspicious_patterns']:
                        matches = re.finditer(pattern, content, re.IGNORECASE | re.MULTILINE)
                        for match in matches:
                            detections.append({
                                'file': config_file,
                                'alias': match.group(),
                                'pattern': pattern,
                                'description': f'在{config_file}中发现可疑别名: {match.group()}'
                            })
                    
                    # 检查常见命令的别名劫持
                    common_commands = ['ls', 'ps', 'netstat', 'who', 'w']
                    for cmd in common_commands:
                        alias_pattern = rf'alias\s+{cmd}\s*='
                        if re.search(alias_pattern, content):
                            detections.append({
                                'file': config_file,
                                'command': cmd,
                                'description': f'在{config_file}中发现{cmd}命令被别名劫持'
                            })
                
                except Exception as e:
                    self.log_error(f"读取配置文件{config_file}失败: {e}")
        
        for detection in detections:
            self.log_detection('SHELL_ALIAS_BACKDOOR', detection)
        
        return len(detections) == 0
    
    def check_process_hiding(self):
        """检测进程隐藏"""
        self.log_info("检测进程隐藏...")
        
        detections = []
        
        # 检查可疑进程
        suspicious_process_names = [
            'log-cleaner',
            'system-monitor',
            'file-monitor',
            'backup-service',
            'maintenance-task'
        ]
        
        success, output, _ = self.run_command("ps aux")
        if success:
            for line in output.split('\n'):
                for suspicious_name in suspicious_process_names:
                    if suspicious_name in line and 'grep' not in line:
                        detections.append({
                            'process': line.strip(),
                            'name': suspicious_name,
                            'description': f'发现可疑进程: {suspicious_name}'
                        })
        
        # 检查隐藏的进程（通过/proc目录）
        try:
            proc_dirs = [d for d in os.listdir('/proc') if d.isdigit()]
            for pid in proc_dirs:
                try:
                    cmdline_path = f'/proc/{pid}/cmdline'
                    if os.path.exists(cmdline_path):
                        with open(cmdline_path, 'r') as f:
                            cmdline = f.read().replace('\x00', ' ').strip()
                        
                        # 检查可疑的命令行
                        if any(name in cmdline for name in suspicious_process_names):
                            detections.append({
                                'pid': pid,
                                'cmdline': cmdline,
                                'description': f'通过/proc发现可疑进程 PID {pid}: {cmdline}'
                            })
                except:
                    continue
        except Exception as e:
            self.log_error(f"检查/proc目录失败: {e}")
        
        for detection in detections:
            self.log_detection('PROCESS_HIDING', detection)
        
        return len(detections) == 0
    
    def check_network_connections(self):
        """检测可疑网络连接"""
        self.log_info("检测可疑网络连接...")
        
        detections = []
        
        # 检查监听端口
        success, output, _ = self.run_command("netstat -tulpn")
        if success:
            suspicious_ports = ['4444', '1337', '31337', '8080', '9999']
            for line in output.split('\n'):
                for port in suspicious_ports:
                    if f':{port}' in line and 'LISTEN' in line:
                        detections.append({
                            'connection': line.strip(),
                            'port': port,
                            'description': f'发现可疑监听端口: {port}'
                        })
        
        # 检查外连接
        success, output, _ = self.run_command("netstat -tupn")
        if success:
            for line in output.split('\n'):
                if 'ESTABLISHED' in line:
                    # 检查连接到可疑IP或端口
                    if re.search(r':(4444|1337|31337|8080|9999)\s', line):
                        detections.append({
                            'connection': line.strip(),
                            'description': f'发现可疑外连接: {line.strip()}'
                        })
        
        for detection in detections:
            self.log_detection('SUSPICIOUS_NETWORK', detection)
        
        return len(detections) == 0
    
    def calculate_stealth_score(self):
        """计算隐蔽性评分"""
        total_checks = 7  # 总检查项数
        passed_checks = 0
        
        # 统计通过的检查项
        detection_types = set(d['type'] for d in self.results['detections'])
        
        check_methods = [
            'SSH_KEY_BACKDOOR',
            'SYSTEMD_SERVICE_BACKDOOR', 
            'CRON_BACKDOOR',
            'ENVIRONMENT_VARIABLE_BACKDOOR',
            'FILE_TRIGGER_BACKDOOR',
            'SHELL_ALIAS_BACKDOOR',
            'PROCESS_HIDING'
        ]
        
        for check_type in check_methods:
            if check_type not in detection_types:
                passed_checks += 1
        
        # 计算评分 (0-100)
        score = int((passed_checks / total_checks) * 100)
        self.results['stealth_score'] = score
        
        return score
    
    def generate_recommendations(self):
        """生成安全建议"""
        recommendations = []
        
        detection_types = set(d['type'] for d in self.results['detections'])
        
        if 'SSH_KEY_BACKDOOR' in detection_types:
            recommendations.append("定期审计SSH authorized_keys文件，移除未授权的密钥")
            recommendations.append("监控SSH密钥文件的变化")
        
        if 'SYSTEMD_SERVICE_BACKDOOR' in detection_types:
            recommendations.append("定期检查系统服务列表，识别可疑服务")
            recommendations.append("监控systemd服务文件的创建和修改")
        
        if 'CRON_BACKDOOR' in detection_types:
            recommendations.append("定期审计crontab任务，检查可疑的定时任务")
            recommendations.append("监控cron配置文件的变化")
        
        if 'ENVIRONMENT_VARIABLE_BACKDOOR' in detection_types:
            recommendations.append("检查profile.d目录中的脚本文件")
            recommendations.append("监控环境变量配置文件的修改")
        
        if 'FILE_TRIGGER_BACKDOOR' in detection_types:
            recommendations.append("监控临时目录中的可疑文件")
            recommendations.append("使用文件完整性监控工具")
        
        if 'SHELL_ALIAS_BACKDOOR' in detection_types:
            recommendations.append("定期检查shell配置文件中的别名定义")
            recommendations.append("监控常用命令的别名劫持")
        
        if 'PROCESS_HIDING' in detection_types:
            recommendations.append("使用多种工具检查进程列表")
            recommendations.append("监控系统进程的异常行为")
        
        # 通用建议
        recommendations.extend([
            "部署EDR/HIDS解决方案进行实时监控",
            "定期进行安全扫描和渗透测试",
            "建立基线配置并监控偏差",
            "实施最小权限原则",
            "启用详细的审计日志"
        ])
        
        self.results['recommendations'] = recommendations
    
    def run_full_check(self):
        """运行完整的隐蔽性检查"""
        self.log_info(f"开始权限维持隐蔽性检查 (会话ID: {self.session_id})")
        
        # 执行各项检查
        checks = [
            self.check_ssh_key_backdoors,
            self.check_systemd_service_backdoors,
            self.check_cron_backdoors,
            self.check_environment_variable_backdoors,
            self.check_file_trigger_backdoors,
            self.check_shell_alias_backdoors,
            self.check_process_hiding,
            self.check_network_connections
        ]
        
        for check in checks:
            try:
                check()
            except Exception as e:
                self.log_error(f"检查失败: {e}")
        
        # 计算评分和生成建议
        score = self.calculate_stealth_score()
        self.generate_recommendations()
        
        self.log_info(f"隐蔽性检查完成，评分: {score}/100")
        
        return self.results
    
    def save_results(self, output_dir="reports"):
        """保存检查结果"""
        os.makedirs(output_dir, exist_ok=True)
        
        # 保存JSON报告
        json_file = os.path.join(output_dir, f"stealth_check_{self.session_id}.json")
        with open(json_file, 'w', encoding='utf-8') as f:
            json.dump(self.results, f, indent=2, ensure_ascii=False)
        
        # 保存Markdown报告
        md_file = os.path.join(output_dir, f"stealth_check_{self.session_id}.md")
        self.generate_markdown_report(md_file)
        
        self.log_info(f"检查结果已保存: {json_file}, {md_file}")
    
    def generate_markdown_report(self, output_file):
        """生成Markdown格式的报告"""
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(f"# Linux权限维持隐蔽性检查报告\n\n")
            f.write(f"**会话ID**: {self.results['session_id']}\n")
            f.write(f"**检查时间**: {self.results['timestamp']}\n")
            f.write(f"**隐蔽性评分**: {self.results['stealth_score']}/100\n\n")
            
            # 评分等级
            score = self.results['stealth_score']
            if score >= 90:
                level = "优秀"
                color = "🟢"
            elif score >= 70:
                level = "良好"
                color = "🟡"
            elif score >= 50:
                level = "一般"
                color = "🟠"
            else:
                level = "较差"
                color = "🔴"
            
            f.write(f"**隐蔽性等级**: {color} {level}\n\n")
            
            # 检测结果
            f.write("## 检测结果\n\n")
            if self.results['detections']:
                detection_by_type = {}
                for detection in self.results['detections']:
                    det_type = detection['type']
                    if det_type not in detection_by_type:
                        detection_by_type[det_type] = []
                    detection_by_type[det_type].append(detection)
                
                for det_type, detections in detection_by_type.items():
                    f.write(f"### {det_type.replace('_', ' ').title()}\n\n")
                    for i, detection in enumerate(detections, 1):
                        f.write(f"{i}. **{detection['details'].get('description', 'Unknown')}**\n")
                        for key, value in detection['details'].items():
                            if key != 'description':
                                f.write(f"   - {key}: `{value}`\n")
                        f.write("\n")
            else:
                f.write("✅ 未发现明显的权限维持痕迹\n\n")
            
            # 安全建议
            f.write("## 安全建议\n\n")
            for i, recommendation in enumerate(self.results['recommendations'], 1):
                f.write(f"{i}. {recommendation}\n")
            
            f.write("\n## 检查项目\n\n")
            check_items = [
                "SSH密钥后门检测",
                "Systemd服务后门检测", 
                "Cron定时任务后门检测",
                "环境变量后门检测",
                "文件触发后门检测",
                "Shell别名后门检测",
                "进程隐藏检测",
                "可疑网络连接检测"
            ]
            
            for item in check_items:
                f.write(f"- {item}\n")
            
            f.write(f"\n---\n*报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n")

def main():
    """主函数"""
    print("Linux权限维持隐蔽性检测器")
    print("=" * 50)
    
    if len(sys.argv) > 1 and sys.argv[1] == '--help':
        print("用法: python3 persistence_stealth_checker.py [选项]")
        print("选项:")
        print("  --help    显示帮助信息")
        print("  --output  指定输出目录 (默认: reports)")
        return
    
    # 解析命令行参数
    output_dir = "reports"
    if len(sys.argv) > 2 and sys.argv[1] == '--output':
        output_dir = sys.argv[2]
    
    # 创建检测器实例
    checker = PersistenceStealthChecker()
    
    try:
        # 运行检查
        results = checker.run_full_check()
        
        # 保存结果
        checker.save_results(output_dir)
        
        # 显示摘要
        print("\n" + "=" * 50)
        print("检查摘要:")
        print(f"隐蔽性评分: {results['stealth_score']}/100")
        print(f"发现问题: {len(results['detections'])} 个")
        print(f"安全建议: {len(results['recommendations'])} 条")
        
        if results['detections']:
            print("\n发现的问题类型:")
            detection_types = set(d['type'] for d in results['detections'])
            for det_type in detection_types:
                count = len([d for d in results['detections'] if d['type'] == det_type])
                print(f"  - {det_type.replace('_', ' ').title()}: {count} 个")
        
    except KeyboardInterrupt:
        print("\n检查被用户中断")
    except Exception as e:
        print(f"检查过程中发生错误: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()